# -*- coding: utf-8 -*-

from gtk import *
from threading import *
import gobject
from photo import *

class ActionHandler(Thread):
	def __init__(self, ppm):
		Thread.__init__(self)
		self.ppm = ppm
		self.actions = []
		self.sem = Semaphore()
		self.stopevent = Event()
		self.photos_pos = 0
		self.photos_tot = 0
		self.exit = False
		
	def run(self):
		self.sem.acquire()
		gdk.threads_enter()
		# le gobject.idle_add c'est une bidouille pour que ca bloque pas sur Windows...
		gobject.idle_add(self.ppm.progress.show)
		gobject.idle_add(self.ppm.stop.show)
		self.ppm.sb.push(self.ppm.sb.get_context_id("load-photos"), "Chargement des images...")
		gdk.threads_leave()
		while len(self.actions) != 0 and not self.stopevent.isSet():
			action = self.actions.pop(0)
			self.sem.release()
			action.execute()
			self.sem.acquire()
		self.sem.release()
		
		gdk.threads_enter()
		self.ppm.sb.pop(self.ppm.sb.get_context_id("load-photos"))
		gobject.idle_add(self.ppm.progress.hide)
		gobject.idle_add(self.ppm.stop.hide)
		gdk.threads_leave()
		
		if self.exit:
			main_quit()
		
	def add_photos(self, photos):
		self.sem.acquire()
		self.actions.insert(0, SearchPhotos(self, photos))
		self.sem.release()
		
	def remove_photos(self, photos):
		self.sem.acquire()
		self.actions.insert(0, RemovePhoto(self, photos))
		self.sem.release()
		
	def stop(self):
		self.stopevent.set()
	
	def quit(self):
		self.exit = True
		self.stopevent.set()
	
class SearchPhotos:
	def __init__(self, handler, path):
		self.handler = handler
		self.path = path
		
	def execute(self):
		self.handler.sem.acquire()
		
		gdk.threads_enter()
		self.handler.ppm.sb.push(self.handler.ppm.sb.get_context_id("load-paths"), "Recherche des images en cours...")
		self.handler.ppm.progress.set_text("")
		gdk.threads_leave()
		
		photos = self.get_photos(self.path)
		
		gdk.threads_enter()
		self.handler.ppm.sb.pop(self.handler.ppm.sb.get_context_id("load-paths"))
		
		self.handler.photos_tot += len(photos)
		if self.handler.photos_tot > 0:
			self.handler.ppm.progress.set_text(str(self.handler.photos_pos) + " sur " + str(self.handler.photos_tot))
			self.handler.ppm.progress.set_fraction(float(self.handler.photos_pos) / self.handler.photos_tot)
		gdk.threads_leave()
		
		for p in photos:
			self.handler.actions.append(AddPhoto(self.handler, p))
		self.handler.sem.release()
		
	def get_photos(self, filenames):
		photos = []
		for filename in filenames:
			if self.handler.stopevent.isSet():
				break
			infos = gdk.pixbuf_get_file_info(filename)
			if infos:
				photos.append((filename, infos))
			elif isdir(filename):
				photos += self.get_photos([join(filename, f) for f in listdir(filename)])
			gdk.threads_enter()
			self.handler.ppm.progress.pulse()
			gdk.threads_leave()
		return photos
		

class AddPhoto:
	def __init__(self, handler, photo):
		self.handler = handler
		self.photo = photo
	def execute(self):
		try:
			photo = Photo(self.photo)
			gdk.threads_enter()
			self.handler.ppm.list.append(photo)
			gdk.threads_leave()
		except PhotoError:
			pass
		except gobject.GError:
			pass
		finally:
			gdk.threads_enter()
			self.handler.photos_pos += 1
			self.handler.ppm.progress.set_text(str(self.handler.photos_pos) + " sur " + str(self.handler.photos_tot))
			self.handler.ppm.progress.set_fraction(float(self.handler.photos_pos) / self.handler.photos_tot)
			gdk.threads_leave()
	
class RemovePhoto:
	def __init__(self, handler, path):
		self.handler = handler
		self.path = path
	def execute(self):
		gdk.threads_enter()
		self.handler.ppm.sb.push(self.handler.ppm.sb.get_context_id("remove-photos"), "Suppression des images...")
		self.handler.ppm.progress.set_text("")
		gdk.threads_leave()
		for p in self.path:
			gdk.threads_enter()
			self.handler.ppm.list.remove(p)
			self.handler.ppm.progress.pulse()
			gdk.threads_leave()
		gdk.threads_enter()
		self.handler.ppm.sb.pop(self.handler.ppm.sb.get_context_id("remove-photos"))
		gdk.threads_leave()
		

	

